﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "global.h"
#include "View/arvindia.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowState(Qt::WindowState::WindowMaximized);
    QSize windowsize = this->size();
    this->setFixedSize(windowsize);
    //初始化调度核
    pDispatchCore = new DispatchCore();

    connect(this,SIGNAL(sig_cmdDelete(int,QString)),pDispatchCore,SLOT(slot_cmdDelete(int,QString)));
    connect(this,SIGNAL(sig_cmdClear()),pDispatchCore,SLOT(slot_cmdClear()));
    connect(this,SIGNAL(sig_getDevArvStatistics()),pDispatchCore,SLOT(slot_getDevArvStatistics()));
    connect(pDispatchCore,SIGNAL(sig_freshPortInfo(QVector<PortGoodsIndicator>,QList<InOutCabCommand_Server>)),this,SLOT(slot_freshPortInfo(QVector<PortGoodsIndicator>,QList<InOutCabCommand_Server>)));
    connect(pDispatchCore,SIGNAL(sig_addCmdToTable(InOutCabCommand_Server)),this,SLOT(slot_addCmdToTable(InOutCabCommand_Server)));
    connect(pDispatchCore,SIGNAL(sig_freshChartView(DevArvStatisticsModel)),this,SLOT(slot_freshChartView(DevArvStatisticsModel)));

    //电机控制页面
    pServoControl = new ServoControl();

    //货位设置页面
    pDeviceSettingsTab = new DeviceSettingsTab();
    //pDeviceSettingsTab->show();
    connect(pDeviceSettingsTab,SIGNAL(sig_sendQRLocateCmd(QRLocateCommand)),pDispatchCore,SLOT(slot_sendQRLocateCmd(QRLocateCommand)));
    connect(pDeviceSettingsTab,SIGNAL(sig_moveCmd(QString,int,int,QString)),pDispatchCore,SLOT(slot_moveCmd(QString,int,int,QString)));
    connect(pDeviceSettingsTab,SIGNAL(sig_subConfigInsertDB(QList<QVariantList>)),pDispatchCore,SLOT(slot_subConfigInsertDB(QList<QVariantList>)));
    connect(pDeviceSettingsTab,SIGNAL(sig_portConfigInsertDB(QList<QVariantList>)),pDispatchCore,SLOT(slot_portConfigInsertDB(QList<QVariantList>)));
    connect(pDispatchCore,SIGNAL(sig_storgeUIRefreshTable()),pDeviceSettingsTab,SLOT(slot_storgeUIRefreshTable()));
    connect(pDeviceSettingsTab,SIGNAL(sig_goodsDistributeCalculate()),pDispatchCore,SLOT(slot_goodsDistributeCalculate()));
    connect(pDeviceSettingsTab,SIGNAL(sig_userInfoInsertDB(QVariantList)),pDispatchCore,SLOT(slot_userInfoInsertDB(QVariantList)));
    connect(pDeviceSettingsTab,SIGNAL(sig_deleteUserInfo(QVariantMap)),pDispatchCore,SLOT(slot_deleteUserInfo(QVariantMap)));
    connect(pDeviceSettingsTab,SIGNAL(sig_updateUserInfo(QVariantMap,QVariantMap)),pDispatchCore,SLOT(slot_updateUserInfo(QVariantMap,QVariantMap)));
    connect(pDispatchCore,SIGNAL(sig_freshUserInfo(QList<QVariantList>)),pDeviceSettingsTab,SLOT(slot_freshUserInfo(QList<QVariantList>)));

    //搜索页面
    pSearchTab = new SearchTab();
    connect(pSearchTab,SIGNAL(sig_sendSearchPost(QVariantMap)),pDispatchCore,SLOT(slot_sendSearchPost(QVariantMap)));
    //启动调度核
    pThread_dispatchCore = new QThread(this);
    connect(pThread_dispatchCore,SIGNAL(started()),pDispatchCore,SLOT(slot_CoreInit()));
    pDispatchCore->moveToThread(pThread_dispatchCore);
    pThread_dispatchCore->start();

    connect(pServoControl,SIGNAL(sig_setParams(int,int,int)),pDispatchCore,SLOT(slot_setParams(int,int,int)));
    connect(pServoControl,SIGNAL(sig_setControl(uint8_t,uint8_t)),pDispatchCore,SLOT(slot_setControl(uint8_t,uint8_t)));
    connect(pServoControl,SIGNAL(sig_addLog(QString,QString)),this,SLOT(slot_addLog(QString,QString)));
    connect(pServoControl,SIGNAL(sig_moveCmd(QString,int,int,QString)),pDispatchCore,SLOT(slot_moveCmd(QString,int,int,QString)));
    connect(pServoControl,SIGNAL(sig_setProbe(quint8,quint8)),pDispatchCore,SLOT(slot_setProbe(quint8,quint8)));
    connect(pServoControl,SIGNAL(sig_inOutCabCmd(InOutCabCommand_Board)),pDispatchCore,SLOT(slot_inOutCabCmd(InOutCabCommand_Board)));
    connect(pDispatchCore,SIGNAL(sig_setParamsResult(QJsonObject)),pServoControl,SLOT(slot_setParamsResult(QJsonObject)));
    connect(pDispatchCore,SIGNAL(sig_ParamsResult(QJsonObject)),pServoControl,SLOT(slot_ParamsResult(QJsonObject)));
    connect(pServoControl,SIGNAL(sig_imgCmd()),pDispatchCore,SLOT(slot_imgCmd()));
    connect(pDispatchCore,SIGNAL(sig_imgCmdResult(QImage)),pServoControl,SLOT(slot_imgCmdResult(QImage)));

    ui->tl_log->document()->setMaximumBlockCount(100);

    loadTableHeader();
    loadPortFile();
    loadChartView();

    connect(ui->chartview,SIGNAL(clicked()),this,SLOT(slot_chartViewClicked()));
    connect(ui->chartview_2,SIGNAL(clicked()),this,SLOT(slot_chartViewClicked()));
}

MainWindow::~MainWindow()
{
    delete ui;
    // 正确关闭线程顺序
    pThread_dispatchCore->quit();
    pThread_dispatchCore->wait();
    pThread_dispatchCore->deleteLater();
    pDispatchCore->deleteLater();

    delete pServoControl;
    delete model;
}

void MainWindow::loadTableHeader()
{
    model = new QStandardItemModel(this); // tableview的数据模型
    ui->tb_cmd->setModel(model);
    ui->tb_cmd->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tb_cmd->horizontalHeader()->setStretchLastSection(true);
    model->setHorizontalHeaderLabels({"指令类型","名称","编号","目标位置","出货口","QR码","状态"});
    ui->tb_cmd->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
    ui->tb_cmd->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);

}

void MainWindow::loadPortFile()
{
    int portcount;  //出货口货位总数量
    if(DeviceDBManager::getInstance()->mPortConfigDB.getRecordsCounts(portcount))
    {
        for(int i=0;i<portcount;i++)
        {
            QLabel *label = new QLabel(ui->fm_port);  // 使用 frame 作为父组件创建 QLabel
            label->setStyleSheet("border-image:url(:/images/graybox.png);");
            label->setMaximumWidth(55);
            label->setText(QString::number(i+1));  // 给标签设置文本内容
            //  设置标签显示文本内容的大小
            QFont ft;
            ft.setBold(true);  //  字体加粗
            ft.setPointSize(15);
            label->setFont(ft);
            label->setAlignment(Qt::AlignHCenter|Qt::AlignTop); //   设置文本处于居中|居上
            label->setIndent(55);//在居上的基础上向下偏移
            ui->fm_port->layout()->addWidget(label);
            mPortFile.append(label);    //添加到列表中
        }
    }
}

void MainWindow::loadChartView()
{
    // 加载第一个饼图数据
    QChart *chart = ui->chartview->chart();
    chart->setAnimationOptions(QChart::AllAnimations);
    chart->legend()->setVisible(true);
    QFont font = chart->legend()->font();
    font.setPointSize(12); // 设置字体大小为 12
    font.setBold(true);     //加粗
    chart->legend()->setFont(font);

    chart->setTheme(QChart::ChartThemeLight);
    chart->setContentsMargins(0,0,0,0); //去掉margin使饼图更大
    chart->setMargins(QMargins(0, 0, 0, 0));
    // 创建QPieSeries对象
    QPieSeries *series = new QPieSeries();
    series->append("占用货位", 1);
    series->append("剩余货位", 1);
//    series->setLabelsVisible(true);
//    series->setLabelsPosition(QPieSlice::LabelPosition::LabelOutside);
    // 修改每个切片的字体大小
    for (QPieSlice *slice : series->slices())
    {
        QString label = slice->label();
        qreal value = slice->value();
        slice->setLabel(QString("%1(%2)").arg(label).arg(value));
    }
    // 将QPieSeries添加到QChart中
    chart->addSeries(series);
    ui->chartview->setRenderHint(QPainter::Antialiasing);  // 设置抗锯齿

    // 加载第二个饼图数据
    chart = ui->chartview_2->chart();
    chart->setAnimationOptions(QChart::AllAnimations);
    chart->legend()->setVisible(true);
    font = chart->legend()->font();
    font.setPointSize(12); // 设置字体大小为 14
    font.setBold(true);
    chart->legend()->setFont(font);

    chart->setTheme(QChart::ChartThemeLight);
    chart->setContentsMargins(0,0,0,0);
    chart->setMargins(QMargins(0, 0, 0, 0));
    // 创建QPieSeries对象
    series = new QPieSeries();
    series->append("在借", 1);
    series->append("在柜", 1);
//    series->setLabelsVisible(true);
//    series->setLabelsPosition(QPieSlice::LabelPosition::LabelOutside);
    // 修改每个切片的字体大小
    for (QPieSlice *slice : series->slices())
    {
        QString label = slice->label();
        qreal value = slice->value();
        slice->setLabel(QString("%1(%2)").arg(label).arg(value));
    }
    // 将QPieSeries添加到QChart中
    chart->addSeries(series);
    ui->chartview_2->setRenderHint(QPainter::Antialiasing);  // 设置抗锯齿
}

void MainWindow::slot_addLog(QString color, QString log)
{
    //mylog<<log;QTime::currentTime()
    QTime time = QTime::currentTime();
    QString logg = QString("<font color='%1'>【%2】%3</font>").arg(color).arg(time.toString("hh:mm:ss")).arg(log);
    ui->tl_log->append(logg);
}

void MainWindow::on_btn_log_clicked()
{
    if(ui->fm_log->isVisible())
    {
        ui->fm_log->setVisible(false);
        ui->btn_log->setText("<<");
    }
    else
    {
        ui->fm_log->setVisible(true);
        ui->btn_log->setText(">>");
    }
}

void MainWindow::slot_addCmdToTable(InOutCabCommand_Server cmd)
{
    QList<QStandardItem*> row;
    row.append(new QStandardItem(cmd.CmdType));
    row.append(new QStandardItem(cmd.Name));
    row.append(new QStandardItem(cmd.CardID));
    QString position = cmd.Face+"面"+QString::number(cmd.LayerNo)+"层"+QString::number(cmd.CellNo)+"格";
    row.append(new QStandardItem(position));
    row.append(new QStandardItem(QString::number(cmd.PortNo+1)));
    row.append(new QStandardItem(cmd.QRCode));
    row.append(new QStandardItem(mStateMap[cmd.CmdState]));

    // 在最后一行插入新数据
    model->insertRow(model->rowCount(), row);
}

void MainWindow::on_btn_cmddelete_clicked()
{
    QItemSelectionModel *pSelectedModel = ui->tb_cmd->selectionModel();
    if(pSelectedModel != nullptr && pSelectedModel->hasSelection())
    {
        //  获取该指令所在的行号
        int Index = pSelectedModel->selectedRows(0).at(0).row();
        QString state = model->item(Index,6)->data(Qt::DisplayRole).toString();
        if(state == mStateMap[CmdState_Running])
        {
            mylog<<"cannot delete the running cmd!";
            return;
        }

        QString qrcode = model->item(Index,5)->data(Qt::DisplayRole).toString();
        model->removeRow(Index);
//        ui->tb_cmd->setModel(model);
        //发送信号通知后端删除指令
        emit sig_cmdDelete(Index,qrcode);
    }
}

void MainWindow::on_btn_cmdclear_clicked()
{
    if(model->rowCount() <= 0) return;

    // 从末尾开始删除
    for(int i = (model->rowCount()-1); i>=0; i--)
    {
        model->removeRow(i);
    }
    //发送信号通知后端清空指令列表
    emit sig_cmdClear();
}

void MainWindow::on_btn_servo_clicked()
{
    pServoControl->show();
}
/***************************************************************
* 函数名称：slot_freshPortInfo(QList<PortGoodsIndicator> portgoods)
* 功能描述：根据调度核中每个出货口货位的状态来修改主页面下发出货口每个货位的状态信息及颜色
* 参数说明：portgoods-调度核中存储的每个出货口货位信息状态
* 返回值说明：
***************************************************************/
void MainWindow::slot_freshPortInfo(QVector<PortGoodsIndicator> portgoods, QList<InOutCabCommand_Server> cmdlist)
{
    for(int i=0;i<mPortFile.size();i++)
    {
        switch (portgoods[i].getState()) {
        //出货口无命令分配，无物理档案占据 ---黑色
        case PortGoodsState::None:
            {
                mPortFile[i]->setStyleSheet("border-image:url(:/images/graybox.png);");
            }
            break;
        //出货口无命令分配，有物理档案占据 ---红色，提示警告占据货位
        case PortGoodsState::PhysicalOccupy:
            {
                mPortFile[i]->setStyleSheet("border-image:url(:/images/redbox.png);");
                slot_addLog("red", QString("检测到出货口第%1格放入一份无关联档案，请及时取出避免影响出入柜指令分配！").arg(i+1));
            }
            break;
        //默认存有命令分配，无物理档案占据，入柜 ---绿色，提示将指定档案放入该位置
        case PortGoodsState::CmdOccupy:
            {
                mPortFile[i]->setStyleSheet("border-image:url(:/images/greenbox.png);");
            }
            break;
        //默认存有命令分配，无物理档案占据，出柜 ---蓝色，等待机械手指令执行完成将目标档案放入该位置
        case PortGoodsState::CmdOccupy|CmdOutCab:
            {
                mPortFile[i]->setStyleSheet("border-image:url(:/images/bluebox.png);");
            }
            break;
        //默认存有命令分配，有物理档案占据，入柜 ---蓝色，等待机械手将目标档案取走并完成指令
        case PortGoodsState::PhysicalOccupy|CmdOccupy:
            {
                mPortFile[i]->setStyleSheet("border-image:url(:/images/bluebox.png);");
            }
            break;
        //默认存有命令分配，有物理档案占据，出柜 ---绿色，提示将目标档案取走
        case PortGoodsState::PhysicalOccupy|CmdOccupy|CmdOutCab:
            {
                mPortFile[i]->setStyleSheet("border-image:url(:/images/greenbox.png);");
            }
            break;
        }
    }
    //清空列表
    if(model->rowCount() <= 0) return;

    // 从末尾开始删除
    for(int i = (model->rowCount()-1); i>=0; i--)
    {
        model->removeRow(i);
    }
    if(!cmdlist.empty())
    {
        for(int i=0;i<cmdlist.size();i++)
        {
            slot_addCmdToTable(cmdlist[i]);
        }
    }

}

void MainWindow::slot_chartViewClicked()
{
    emit sig_getDevArvStatistics();
}

void MainWindow::slot_freshChartView(DevArvStatisticsModel response)
{
    QChart *chart = ui->chartview->chart();
    // 获取所有系列
    QList<QAbstractSeries *> seriesList = chart->series();

    if(seriesList.isEmpty())
        return;

    //执行向 QPieSeries 的静态类型转换
    QPieSeries *pieSeries = static_cast<QPieSeries *>(seriesList.first());

    // 确保成功转换为 QPieSeries
    if (pieSeries == nullptr)
        return;

    QPieSlice *slice = pieSeries->slices().at(0); // 第一个切片即为 Item 1
    slice->setValue(response.receivedArvNum);
    QString label = slice->label();
    qreal value = slice->value();
    slice->setLabel(QString("占用货位(%1)").arg(value));

    slice = pieSeries->slices().at(1); // 第一个切片即为 Item 1
    slice->setValue(response.resLocationNum);
    label = slice->label();
    value = slice->value();
    slice->setLabel(QString("剩余货位(%1)").arg(value));

    seriesList.clear();
    pieSeries = nullptr;
    chart = ui->chartview_2->chart();
    // 获取所有系列
    seriesList = chart->series();

    if(seriesList.isEmpty())
        return;

    //执行向 QPieSeries 的静态类型转换
    pieSeries = static_cast<QPieSeries *>(seriesList.first());

    // 确保成功转换为 QPieSeries
    if (pieSeries == nullptr)
        return;

    slice = pieSeries->slices().at(0); // 第一个切片即为 Item 1
    slice->setValue(response.borrowArvNum);
    label = slice->label();
    value = slice->value();
    slice->setLabel(QString("在借(%1)").arg(value));

    slice = pieSeries->slices().at(1); // 第一个切片即为 Item 1
    slice->setValue(response.indeskArvNum);
    label = slice->label();
    value = slice->value();
    slice->setLabel(QString("在柜(%1)").arg(value));

}

void MainWindow::on_btn_setup_clicked()
{
    pDeviceSettingsTab->show();
}

void MainWindow::on_btn_search_clicked()
{
    pSearchTab->show();
}

void MainWindow::on_btn_opendoor_5_clicked()
{
    ArvInDialog* aa = new ArvInDialog();

    aa->exec();
}
